<?php

App::uses('CakeEmail', 'Network/Email');
require APP . '/Vendor/bootstrap.php';
APIContext::set($apiContext);

class APIContext {

    public static $apiContext;

    public static function set($apiContext) {
        self::$apiContext = $apiContext;
    }

    public static function get() {
        return self::$apiContext;
    }

}

class PaypalController extends AppController {

    public $name = 'Paypal';
    public $uses = array('Transaction', 'User', 'Order', 'OrderDetail', 'ProductLink', 'DownloadCount');
    private $currency_default = 'EUR';

    public function index() {
        if (isset($this->request->query['customer_note'])) {
            if ($user = $this->Session->read('user')) {
                if ($shopping_cart = $this->Session->read('shopping_cart')) {
                    //set API Context
                    $apiContext = APIContext::get();

                    //set default Currentcy
                    $defaultCurrency = $this->currency_default;

                    $date = date('Y-m-d');

                    //set payer
                    $payer = new PayPal\Api\Payer();
                    $payer->setPaymentMethod("paypal");

                    $item = array();
                    $tong_tien = 0;
                    foreach ($shopping_cart as $key => $value) {
                        $this_item = new PayPal\Api\Item();
                        $this_item->setName($value['Product']['name'])
                                ->setCurrency($defaultCurrency)
                                ->setQuantity($value['so_luong'])
                                ->setPrice($value['Product']['price']);
                        $tong_tien += $value['so_luong'] * $value['Product']['price'];
                        $item[] = $this_item;
                    }

                    $itemList = new PayPal\Api\ItemList();
                    $itemList->setItems($item);

                    $details = new \PayPal\Api\Details();
                    $details->setShipping('0.00')
                            ->setTax('0.00')
                            ->setSubtotal($tong_tien);

                    $amount = new \PayPal\Api\Amount();
                    $amount->setCurrency($defaultCurrency)
                            ->setTotal($tong_tien)
                            ->setDetails($details);


                    $transaction = new \PayPal\Api\Transaction();
                    $transaction->setAmount($amount)
                            ->setItemList($itemList)
                            ->setDescription("Payment description");

                    $redirectUrls = new \PayPal\Api\RedirectUrls();
                    $redirectUrls->setReturnUrl(DOMAIN . "Paypal/payment_response?success=true")
                            ->setCancelUrl(DOMAIN . "Paypal/payment_response?success=false");

                    $payment = new \PayPal\Api\Payment();
                    $payment->setIntent("sale")
                            ->setPayer($payer)
                            ->setRedirectUrls($redirectUrls)
                            ->setTransactions(array($transaction));

                    CakeLog::write('Paypal-' . $date, 'BAT DAU GUI SANG PAYPAL');
                    try {
                        $payment->create($apiContext);
                    } catch (PayPal\Exception\PPConnectionException $ex) {
                        CakeLog::write('Paypal-' . $date, 'ERROR - GUI THONG TIN SANG PAYPAL. Exception: ' . $ex->getMessage() . " \r\n");
                    }

                    foreach ($payment->getLinks() as $link) {
                        if ($link->getRel() == 'approval_url') {
                            $redirectUrl = $link->getHref();
                            break;
                        }
                    }

                    if (isset($redirectUrl)) {
                        //log du lieu gui sang paypal
                        $token_url = explode('&token=', $redirectUrl);
                        if (!empty($token_url))
                            $token = $token_url[1];
                        else
                            $token = 'Token Empty';
                        $str_log = 'THONG TIN GUI SANG PAYPAL: PaymentID: ' . $payment->getId();
                        $str_log .= ' | Token: ' . $token;
                        $str_log .= ' | Redirect Url: ' . $redirectUrl;
                        $str_log .= ' | time: ' . date('H:i:s d-m-Y') . " \r\n";
                        CakeLog::write('Paypal-' . $date, $str_log);

                        //chen thong tin gio hang
                        $order = array(
                            'user_id' => $user['User']['id'],
                            'number_product' => count($shopping_cart),
                            'total_amount' => $tong_tien,
                            'status' => 0,
                            'payment_status' => 0
                        );
                        if ($this->Order->save($order)) {
                            $order_id = $this->Order->getLastInsertID();
                            $order_detail = array();
                            foreach ($shopping_cart as $key => $value) {
                                $order_detail[] = array(
                                    'order_id' => $order_id,
                                    'product_id' => $value['Product']['id'],
                                    'number_product' => $value['so_luong']
                                );
                            }
                            if ($this->OrderDetail->saveAll($order_detail)) {
                                //chen thong tin thanh toan
                                $payment_id = $payment->getId();
                                $trans = array(
                                    'payment_id' => $payment_id,
                                    'payment_token' => $token,
                                    'order_id' => $order_id,
                                    'status' => 1
                                );
                                if ($this->Transaction->save($trans)) {
                                    //redirect sang trang thanh toan
                                    $this->redirect($redirectUrl);
                                } else {
                                    CakeLog::write('Paypal-' . $date, 'ERROR: Insert transaction to database. Payment_id: ' . $payment_id . ' | Payment_token: ' . $token . ' | order_id: ' . $order_id . " \r\n");
                                }
                            } else {
                                CakeLog::write('Paypal-' . $date, 'ERROR: Insert chi tiet don hang. Order_id: ' . $order_id . ' | Shopping_cart: ' . json_encode($shopping_cart) . " \r\n");
                            }
                        } else {
                            CakeLog::write('Paypal-' . $date, 'ERROR: Insert order vao database. User_id: ' . $user['User']['id'] . " \r\n");
                        }
                    } else {
                        echo '<script>alert("Have an error when request to paypal. Please try again later!"); location.href="/check-out";</script>';
                        die;
                    }
                } else {
                    $this->redirect(array('controller' => 'Product', 'action' => 'checkout'));
                }
            } else {
                $this->redirect(array('controller' => 'User', 'action' => 'login', '?' => array('redirect' => $this->here)));
            }
        } else {
            $this->redirect(array('controller' => 'Product', 'action' => 'checkout'));
        }
    }

    /*
     * function get payment response
     * author: Nguyen Tat Loi
     * date: 23/7/2014
     */

    public function payment_response() {
        $get = $this->params->query;
        $time = date('H:i:s d-m-Y');
        $date = date('Y-m-d');
        if (!empty($get['success']) && !empty($get['token'])) {

            $str_log = "PAYPAL RESPONSE: success: {$get['success']} | token: {$get['token']} | time: {$time}";
            if (!empty($get['PayerID']))
                $str_log .= ' | PayerID: ' . $get['PayerID'] . " \r\n";
            CakeLog::write('Paypal-' . $date, $str_log);
            //get from db by token
            $token = $get['token'];
            $transaction = $this->Transaction->findByPaymentToken($token);
            if (!empty($transaction)) {
                $order_id = $transaction['Transaction']['order_id'];
                //Xoa gio hang
                $this->Session->delete('shopping_cart');

                if ($get['success'] == 'true') {
                    if (!empty($get['PayerID'])) {
                        $payer_id = $get['PayerID'];
                        //get payment info
                        $paypal_id = $transaction['Transaction']['payment_id'];
                        $apiContext = APIContext::get();
                        $payment = \PayPal\Api\Payment::get($paypal_id, $apiContext);

                        $execution = new \PayPal\Api\PaymentExecution();
                        $execution->setPayerId($get['PayerID']);
                        $result = $payment->execute($execution, $apiContext);
                        $result = $result->toArray();
                        if ($result['state'] == 'approved') {
                            $payment_info = $payment->toArray();
                            if ($payment_info['payer']['payer_info']['payer_id'] == $payer_id) {
                                $order = array(
                                    'id' => $order_id,
                                    'payment_status' => 1
                                );
                                $this->Order->save($order);

                                $order_detail = $this->OrderDetail->findAllByOrderId($order_id);

                                $check = $this->Order->find(
                                        'first', array(
                                    'conditions' => array(
                                        'Order.id' => $order_id
                                    )
                                        )
                                );
                                try {
                                    foreach ($order_detail as $od) {
                                        $products_ids[] = $od['OrderDetail']['product_id'];
                                    }
                                    $product_links = $this->ProductLink->find(
                                            'all', array(
                                        'conditions' => array(
                                            'ProductLink.product_id' => $products_ids
                                        )
                                            )
                                    );
                                    foreach ($product_links as $pl) {
                                        $downloadCounts[] = array(
                                            'uid' => $check['User']['id'],
                                            'product_link_id' => $pl['ProductLink']['id'],
                                            'order_id' => $order_id,
                                            'turn_left' => 2
                                        );
                                    }
                                    $this->DownloadCount->saveAll($downloadCounts);
                                } catch (Exception $e) {
                                    CakeLog::write('Download-' . $date, 'ERROR: Lỗi lưu download cho. User_id: ' . $check['User']['id'] . " \r\n");
                                }

                                try {
                                    //Sent email
                                    $Email = new CakeEmail();
                                    $Email->config('default')
                                            ->template('order')
                                            ->emailFormat('html')
                                            ->to($check['User']['email'])
                                            ->subject('3DArcshop Payment Infomation')
                                            ->viewVars(array(
                                                'order' => $check,
                                                'order_detail' => $order_detail
                                            ))
                                            ->send();
                                } catch (Exception $e) {
                                    CakeLog::write('Email-' . $date, 'ERROR: Lỗi gửi email cho. User_id: ' . $check['User']['id'] . " \r\n");
                                }
                                $this->redirect(array('controller' => 'User', 'action' => 'order', $order_id));
                            } else {
                                echo '<h1>404 Not Found</h1><br/>';
                                echo '<i>Your request link is not exist or deleted by admin. Please contact to Administrator for more information.</i>';
                                die;
                            }
                        } else {
                            $order = array(
                                'id' => $order_id,
                                'payment_status' => 2
                            );
                            $this->Order->save($order);
                        }
                    } else {
                        echo '<h1>404 Not Found</h1><br/>';
                        echo '<i>Your request link is not exist or deleted by admin. Please contact to Administrator for more information.</i>';
                        die;
                    }
                } else {
                    $order = array(
                        'id' => $order_id,
                        'payment_status' => 2
                    );
                    $this->Order->save($order);
                }
                $this->redirect(array('controller' => 'User', 'action' => 'order', $order_id));
            } else {
                echo 'Transaction not exist';
                die;
            }
        } else {
            echo '<h1>404 Not Found</h1><br/>';
            echo '<i>Your request link is not exist or deleted by admin. Please contact to Administrator for more information.</i>';
            die;
        }
    }

    /*
     * function pay for order by order id
     * author: Nguyen Tat Loi
     * date: 31/7/2014
     */

    public function pay_by_order($order_id) {
        if (!empty($order_id)) {
            if ($user = $this->Session->read('user')) {
                $user_id = $user['User']['id'];
                if ($order = $this->Order->check_order_by_user($order_id, $user_id)) {
                        $transaction = $this->Transaction->findByOrderId($order_id);
                        if (!empty($transaction)) {
                            if ($transaction['Transaction']['payment_status'] != '1') {
                                $payment_id = $transaction['Transaction']['payment_id'];
								try{
									//set API Context
									$apiContext = APIContext::get();
									$payment = \PayPal\Api\Payment::get($payment_id, $apiContext);
									$payment_info = $payment->toArray();
									foreach ($payment_info['links'] as $link) {
										if ($link['rel'] == 'approval_url') {
											$redirectUrl = $link['href'];
											break;
										}
									}

									if (isset($redirectUrl))
										$this->redirect($redirectUrl);
									else
										$this->redirect(array('controller' => 'User', 'action' => 'userinfo'));
								}catch(Exception $e) {
									echo "<script>alert('Your order was expired! Please create another order to buy our products.'); window.location.href = '/account';</script>";
								}		
                            }else {
                                $this->redirect(array('controller' => 'User', 'action' => 'userinfo'));
                            }
                        } else {
                            $this->redirect(array('controller' => 'User', 'action' => 'userinfo'));
                        }                    
                } else {
                    $this->redirect(array('controller' => 'User', 'action' => 'userinfo'));
                }
            } else {
                $this->redirect('/');
            }
        } else {
            $this->redirect('/');
        }
    }

}

?>